package com.ctvit.struts.common;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;


import com.cctv.portal.sms.adapter.SmsAdapter;
import com.cctv.portal.sms.adapter.ws.RespBody;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.hibernate.id.GUIDGenerator;

//import com.cctv.eip.messagingplatformservice._0.MessageCommonDataType;
//import com.cctv.eip.messagingplatformservice._0_1.EIPMessagePortType;
//import com.cctv.eip.messagingplatformservice._0_1.EIPMessagingPlatformService;
//import com.cctv.esb.schema.messagehead._0.RequestHeadType;
import com.cctv.eip.messagingplatformservice._0.MessageCommonDataType;
import com.cctv.eip.messagingplatformservice._0_1.EIPMessagePortType;
import com.cctv.eip.messagingplatformservice._0_1.EIPMessagingPlatformService;
import com.cctv.esb.schema.messagehead._0.RequestHeadType;
import com.ctvit.framework.log.Log4jPrintStream;
import com.ctvit.framework.log.Log4jPrintStreamErr;
import com.ctvit.framework.security.LdapPasswordEncoder;
import com.ctvit.framework.web.context.ContextHolder;
import com.ctvit.sms.platform.domain.Contentlog;
import com.ctvit.sms.platform.domain.Login;
import com.ctvit.sms.platform.domain.SendTaskBean;
import com.ctvit.sms.platform.service.AppOnlyService;
import com.ctvit.sms.platform.service.SmsService;
import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.impl.SingleMessage;
import com.gexin.rp.sdk.base.impl.Target;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.template.NotificationTemplate;
import com.gexin.rp.sdk.template.TransmissionTemplate;

public class CommonFunc {
	protected final static Log log = LogFactory.getLog(CommonFunc.class);
	public static String smsServerPort = "";
	public static String smsServerHost = "";
	public static String synAllPerson="";
	public static String delayString="";//请求延时长度
	public static int intervalSec=0;
	public static String maxCnt="";
	public static String startTimer="";
	public static String redisHost="";
	public static int redisPort=0;
	public static String sysid="";
	public static String remoteFileDir="";
	public static String remoteFileRecvUrl="";
	public static String userId = "00213030";
	private static String host="http://sdk.open.api.igexin.com/apiex.htm";
	private static String appkey="MG0UoDc9vh6uCMs5F9fc91";
	private static String appId="tXRwidBJVV8WNqZUx4VCv8";
	private static String master="T89cErBK0r8RqEGL136Lw8";
	public static String gatewayUrl="";
	public static String nasFileDir="";
	public static String lastFileTime; //最后一次循环文件时间
	
	//是否启用短信即时发送
	public static String isSmsEnabled="";
	
	static Properties pro=new Properties();
	
	static {
        Log4jPrintStream.redirectSystemOut();
        Log4jPrintStreamErr.redirectSystemErr();
    }
	static{
		InputStream inStream=Thread.currentThread().getContextClassLoader().getResourceAsStream("config/database.properties");
		
		try{
			pro.load(inStream);
		}catch(IOException io){
			io.printStackTrace();
		}
		nasFileDir=pro.getProperty("nas.filedir");
		smsServerHost =pro.getProperty("sms.host");
		smsServerPort=pro.getProperty("sms.port");
		synAllPerson=pro.getProperty("ldap.synall");
		startTimer=pro.getProperty("smssys.starttimer");
		redisHost=pro.getProperty("redis.host");
		redisPort=Integer.valueOf(pro.getProperty("redis.port")).intValue();
		sysid=pro.getProperty("sysid");
		remoteFileDir=pro.getProperty("remote_file_dir");
		remoteFileRecvUrl=pro.getProperty("remote_file_recv_url");
		gatewayUrl=pro.getProperty("gateway_url");
		isSmsEnabled=pro.getProperty("isSmsEnabled");
		lastFileTime=pro.getProperty("lastFileTime");
	}
	
	public static void setLastFileTime(String lastFileTime)throws Exception {
		CommonFunc.lastFileTime = lastFileTime;
		pro.setProperty("lastFileTime", CommonFunc.lastFileTime);
		String path = Thread.currentThread().getContextClassLoader().getResource("config/database.properties").getPath();
        FileOutputStream outputFile = new FileOutputStream(path);  
        pro.store(outputFile, "modify");  
        outputFile.close();  
        outputFile.flush(); 
	}
	
	private static int socketTimeout = 15000;
	private static final int connectTimeout = 15000;
	public static String postJsonTo(String jsonString,String url){
		String ret = null;
		try {
			FileOutputStream fs=null;
			InputStream inStream=null;
			OutputStream outputStream=null;
			int bytesRead = -1;
			byte[] buffer = new byte[1204];
			URL urlRecv = null; //new URL("");
//			if(url!= null){
			if(StringUtils.isEmpty(url)){
			   urlRecv = new URL(url);
			}else{
			   urlRecv = new URL(CommonFunc.remoteFileRecvUrl);
			};
			
	        HttpURLConnection httpConn;
				httpConn = (HttpURLConnection)urlRecv.openConnection();
	        httpConn.setUseCaches(false);
	        httpConn.setDoOutput(true);
	        httpConn.setRequestMethod("POST");
//	        httpConn.setRequestProperty("data", jsonString);
			PrintWriter pw = new PrintWriter(httpConn.getOutputStream());
			pw.print("info="+jsonString);
			pw.flush();
			pw.close();
			System.out.println("postJsonTo-jsonString="+jsonString);
//	        outputStream = httpConn.getOutputStream();

//			inStream=httpConn.getInputStream();
//	        while ((bytesRead = inStream.read(buffer)) != -1) {
//	            outputStream.write(buffer, 0, bytesRead);
//	        }
	        int responseCode = httpConn.getResponseCode();
	        if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
		        ret = reader.readLine();
		        System.out.println("postJsonTo-ret="+ret);
	        } else {
	        	log.info("transfer jsontr error=" + responseCode);
	        }
//	        ret = outputStream.toString();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}
	public static final String soapXml(SoapHeader sh,String value){
		//此处拼接Xml文件
		String soapXml = IConst.soapXml;
		soapXml = soapXml.replace("SSID", sh.getSourceSysID()).replace("TSID", sh.getTargetSysID()).replace("TS", sh.getTargetService()).replace("RID", sh.getRequestID()).replace("VALUE", value);
		return soapXml;
	}
	public static final String soapPost(String soapAddr, String xString,Contentlog contentlog) throws Exception{
		SoapHeader sh=new SoapHeader(contentlog.getZSourceSysId(), contentlog.getZTargetSysId(),contentlog.getZTargetService(), "requestID");
		String soapXmlS=soapXml(sh,xString);
		CloseableHttpClient httpclient = HttpClients.createDefault();
		String soapResult = null;
        try{
            HttpPost httpPost = new HttpPost(soapAddr);
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
            		.setConnectTimeout(connectTimeout).build();
            httpPost.setConfig(requestConfig);
            StringEntity entiy = new StringEntity(soapXmlS,ContentType.create(ContentType.APPLICATION_XML.getMimeType(), "UTF-8"));
            entiy.setContentType("application/xml");
            httpPost.setEntity(entiy);
            httpPost.setHeader("Content-Type","application/soap+xml; charset=UTF-8");
            httpPost.setHeader("SOAPAction", "http://schemas.xmlsoap.org/soap/envelope/");
//            httpPost.setHeader("User-Agent", "CTVIT SIGNATURE SERVER");
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
                public String handleResponse(
                        final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        String result =  (entity != null ? EntityUtils.toString(entity,"UTF-8") : null);
                        if(log.isDebugEnabled()){
                        	log.debug("调用成功！返回结果为:\n{}"+result);
                        }
                        return result;
                    } else {
                    	if(log.isDebugEnabled()){
                        	log.debug("调用失败！错误码:\n{}"+status);
                        }
                        throw new ClientProtocolException("Unexpected response status: " + status );
                    }
                }
           };
            soapResult = httpclient.execute(httpPost, responseHandler);
        } catch(ClientProtocolException e){
        	soapResult = e.getMessage();
        	throw e;
        } catch(IOException e){
        	soapResult = e.getMessage();
        	throw e;
        } finally {
            try {
				httpclient.close();
			} catch (Exception e) {
//				e.printStackTrace();
				httpclient = null;
				throw e;
			}
        }
        contentlog.setZState("0");
        contentlog.setZResponseContent(soapResult);
        contentlog.setZCrtim(new Timestamp(System.currentTimeMillis()));
        SmsService smsService = ContextHolder.getBean(SmsService.class);
        smsService.insertContengLog(contentlog);
        return soapResult;
	}
	public static boolean validateRequest(HttpServletRequest request) {
		String accessToken=request.getParameter("accessToken");
//		accessToken=URLDecoder.decode(accessToken);
		String userId = request.getParameter("userId");
		AppOnlyService appOnlyService = ContextHolder.getBean(AppOnlyService.class);
		Login login=appOnlyService.getUserLoginInfo(userId);
		String saltAccessToken="";
		boolean validFail=false;
		if (login!=null){
			LdapPasswordEncoder ldapPasswordEncoder=ContextHolder.getBean("passwordEncoder");
			saltAccessToken=ldapPasswordEncoder.encodePassword(login.getZAccessToken(),login.getZSalt().getBytes());
			if (login.getZAccessExpired().before(new Timestamp(Calendar.getInstance().getTimeInMillis()))){
				validFail=true;
			}else if (!saltAccessToken.equals(accessToken)){
				validFail=true;
			}
		}else{
			validFail=true;
		}
		return validFail;
	}
	/**
	 * 参考http://caibaojian.com/phone-regexp.html
	 * js的regx在jquery.easyui.extend.jszhong
	 * @param mobile
	 * @return
	 */
	public static boolean isMobileValid(String mobile){
		if (org.apache.commons.lang.StringUtils.isEmpty(mobile)){
			return false;
		}else{
			return mobile.matches("^(1)[3|4|5|7|8|9]\\d{9}$");
		}
	}
	public static String pushMsg(String userId,String push_title,String push_content,String clientid )throws Exception{
		IPushResult ret=null;String reString="";
		try {
			IGtPush push = new IGtPush(host, appkey, master);
			push.connect();
			NotificationTemplate template =null;
			TransmissionTemplate transmissionTemplate=null;
			TransmissionTemplate transmissionTemplateAndroid = null;
			SingleMessage message = new SingleMessage();
			Target target1 = null;
			String[] clientsStrings=clientid.split(",");
			template = NotificationTemplateDemo(push_content,push_title);
			if (clientsStrings.length>1&&"ios".equals(clientsStrings[1])){
				transmissionTemplate=transmissionTemplateDemo(push_content,push_title,userId);
			}
			
			
			message = new SingleMessage();
			message.setOffline(true);
			message.setOfflineExpireTime(1 * 1000 * 3600);
			message.setData(template);
			if (clientsStrings.length>1&&"ios".equals(clientsStrings[1])){
				message.setData(transmissionTemplate);
			}
			target1 = new Target();
			target1.setAppId(appId);
			target1.setClientId(clientsStrings[0]);
			ret = push.pushMessageToSingle(message, target1);
			if (!(clientsStrings.length>1&&"ios".equals(clientsStrings[1]))){
				transmissionTemplateAndroid = transmissionTemplateAndroid(push_content,push_title);
				message.setData(transmissionTemplateAndroid);
				ret = push.pushMessageToSingle(message, target1);
			}
		} catch (Exception e) {
			log.error(e);
			e.printStackTrace();
		}
		if (ret!=null){
			reString=ret.getResultCode().toString();
		}
		return reString;
	}
	
	

	
	
	public  static NotificationTemplate NotificationTemplateDemo(String content,String title)
	throws Exception {
		NotificationTemplate template = new NotificationTemplate();
		template.setAppId(appId);
		template.setAppkey(appkey);
		template.setTitle(content);
		template.setText(title);
		template.setLogo("icon.png");
		// template.setLogoUrl("");
		// template.setIsRing(true);
		// template.setIsVibrate(true);
		// template.setIsClearable(true);
		template.setTransmissionType(1);
		template.setTransmissionContent("dddd");
		// template.setPushInfo("actionLocKey", 2, "message", "sound",
		// "payload", "locKey", "locArgs", "launchImage");
		return template;
}
	//给安卓发送透传消息，但数据格式是错误的为了触发receive
	public static TransmissionTemplate transmissionTemplateAndroid(String content,String title) throws Exception{
	    TransmissionTemplate template = new TransmissionTemplate();
	    template.setAppId(appId);
	    template.setAppkey(appkey);
	    // 透传消息设置，1为强制启动应用，客户端接收到消息后就会立即启动应用；2为等待应用启动
	    template.setTransmissionType(2);
	    template.setTransmissionContent(content);
//	    template.setPushInfo(content, 3, "message", "sound", "payload",title, "locArgs", "launchImage");

	    // 设置定时展示时间
	    // template.setDuration("2015-01-16 11:40:00", "2015-01-16 12:24:00");
	    return template;
	}
	
	
	public static TransmissionTemplate transmissionTemplateDemo(String content,String title,String userId) throws Exception{
	    TransmissionTemplate template = new TransmissionTemplate();
	    template.setAppId(appId);
	    template.setAppkey(appkey);
	    // 透传消息设置，1为强制启动应用，客户端接收到消息后就会立即启动应用；2为等待应用启动
	    template.setTransmissionType(1);
	    template.setTransmissionContent(content);
	    
	    //得到短消息和通知未读数据条数之和
	    System.out.println("---------------------------111111111111----------------------------------");
	    AppOnlyService appOnlyService = ContextHolder.getBean(AppOnlyService.class);
	    int sum = appOnlyService.doGetMessageSum(userId);
	    System.out.println("---------------------------222222222222222----------------------------------"+sum);
	    
	    template.setPushInfo("查看未阅读的消息", sum, "message", "sound", "payload",title, "locArgs", "launchImage");

	    // 设置定时展示时间
	    // template.setDuration("2015-01-16 11:40:00", "2015-01-16 12:24:00");
	    return template;
	}
	public static String sendSMS(SendTaskBean sendTaskBean) {
		return "";
	}
	/**
	 * 1:succ,2:fail
	 * @param sendTaskBean
	 * @return
	 */
	public static String sendSMS(String userId,String content) {
		String rt="false";
//		rt="ok";
		try {
//		调用portal提供的webservice 直接通过短信网关发送短信
//			QName SERVICE_NAME = new QName("http://cctv.com/eip/messagingPlatformService/0.1", "EIPMessagingPlatformService");
//			URL wsdlURL = EIPMessagingPlatformService.WSDL_LOCATION;
//	        EIPMessagingPlatformService ss = new EIPMessagingPlatformService(wsdlURL, SERVICE_NAME);
//	        EIPMessagePortType port = ss.getEIPSendMessagingPort();  
//	        
//	        RequestHeadType _sendMessage_requestHead = new RequestHeadType();
//	        MessageCommonDataType _sendMessage_messageRequest = new MessageCommonDataType();
//	        _sendMessage_requestHead.setSourceSysID("EF06");
//	        _sendMessage_requestHead.setTargetSysID("EF03");
//	        _sendMessage_requestHead.setRequestID(UUID.randomUUID().toString());
//	        _sendMessage_requestHead.setTargetService("MessagingPlatformService");
//	        _sendMessage_messageRequest.setMessageType("2");//短信
//	        _sendMessage_messageRequest.setAppBidType("EF06");
//	        _sendMessage_messageRequest.setContentType(sendTaskBean.getZMsgContent());
//	        _sendMessage_messageRequest.setRecvsType(sendTaskBean.getZRecvUsr());
//	        _sendMessage_messageRequest.setTitleType("节目生产系统提醒");
//	        com.cctv.eip.messagingplatformservice._0.ResponseType _sendMessage__return = port.sendMessage(_sendMessage_requestHead, _sendMessage_messageRequest);
//	        rt=_sendMessage__return.getStatus();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return rt;
	}

	/**
	 * 批量发送短信
	 *
	 * @param destnumbers  英文逗号隔开的手机号 单个发送时 只需传入手机号
	 * @param content
	 * @return
	 */
	public static RespBody batchSendSMS(String destnumbers, String content) {
		String rt = "false";
		RespBody result=new RespBody();
		try {
			result = SmsAdapter.send(destnumbers, content);
			Class cls=getCallerClass(2);
//			log.debug("send sms caller==="+cls);
		} catch (Exception e) {
			log.error(e);
			result.setCode(e.toString());
			return result;
		}
		return result;
	}
	public static Class getCallerClass(int level) throws ClassNotFoundException {
        StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
        String rawFQN = stElements[level+1].toString().split("\\(")[0];
        return Class.forName(rawFQN.substring(0, rawFQN.lastIndexOf('.')));
    }
	public static String dealWithFirstChar(String jsonInput){
		String originalInput = jsonInput;
		StringBuffer inputStr = new StringBuffer(jsonInput);
		String regex = "\"(\\w+)\":";
		Pattern p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(inputStr);
		List result=new ArrayList();
		while(m.find()){
			String valueName = m.group(1);
			String newValueName = null;
			char[] words =valueName.toCharArray();
			if(Character.isUpperCase(words[0])){//首字母大写,不符合变量命名规范

				words[0] = Character.toLowerCase(words[0]);
				newValueName = new String(words);
//				System.out.println("orignal value:"+valueName+" new value :"+ newValueName);
//				String regexWord = "\""+valueName+"\":";
				String regx1 = "\""+valueName+"\":";
				String replace = "\""+newValueName+"\":";
				originalInput=originalInput.replaceAll(regx1, replace);
			}
			result.add(valueName);
			inputStr.delete(0, m.end(0));
			m=p.matcher(inputStr);
		}
		return originalInput;

	}
	/**
    * 将一个 JavaBean 对象转化为一个  Map
    * @param bean 要转化的JavaBean 对象
    * @return 转化出来的  Map 对象
    * @throws IntrospectionException 如果分析类属性失败
    * @throws IllegalAccessException 如果实例化 JavaBean 失败
    * @throws InvocationTargetException 如果调用属性的 setter 方法失败
    */
   public static Map convertBean(Object bean)
           throws IntrospectionException, IllegalAccessException, InvocationTargetException {
       Class type = bean.getClass();
       Map returnMap = new HashMap();
       BeanInfo beanInfo = Introspector.getBeanInfo(type);

       PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
       for (int i = 0; i< propertyDescriptors.length; i++) {
           PropertyDescriptor descriptor = propertyDescriptors[i];
           String propertyName = descriptor.getName();
           if (!propertyName.equals("class")) {
               Method readMethod = descriptor.getReadMethod();
               Object result = readMethod.invoke(bean, new Object[0]);
               if (result != null) {
                   returnMap.put(propertyName, result);
               } else {
                   returnMap.put(propertyName, "");
               }
           }
       }
       return returnMap;
   }
	/**
    * 将一个 Map 对象转化为一个 JavaBean
    * @param type 要转化的类型
    * @param map 包含属性值的 map
    * @return 转化出来的 JavaBean 对象
    * @throws IntrospectionException
    *             如果分析类属性失败
    * @throws IllegalAccessException
    *             如果实例化 JavaBean 失败
    * @throws InstantiationException
    *             如果实例化 JavaBean 失败
    * @throws InvocationTargetException
    *             如果调用属性的 setter 方法失败
    */
   public static Object convertMap(Class type, Map map)
           throws IntrospectionException, IllegalAccessException,
           InstantiationException, InvocationTargetException {
       BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
       Object obj = type.newInstance(); // 创建 JavaBean 对象

       // 给 JavaBean 对象的属性赋值
       PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
       for (int i = 0; i< propertyDescriptors.length; i++) {
           PropertyDescriptor descriptor = propertyDescriptors[i];
           String propertyName = descriptor.getName();

           if (map.containsKey(propertyName)) {
               // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
               Object value = map.get(propertyName);

               Object[] args = new Object[1];
               args[0] = value;

               descriptor.getWriteMethod().invoke(obj, args);
           }
       }
       return obj;
   }
}
